<?php

declare(strict_types=1);

namespace app\service\user;

use app\model\RegionUser;
use app\model\User;
use think\facade\Log;
use think\facade\Request;

class VerifyService
{
    private const RULES = [
        'SUCCESS' => [
            'code' => 200,
            'msg' => '登录验证通过',
            'action' => 'proceed',
        ],
        'NEED_BIND_PHONE' => [
            'code' => 4001,
            'msg' => '请先绑定手机号',
            'action' => 'need_bind_phone',
        ],
        'NEED_COMPANY_AUTH' => [
            'code' => 4002,
            'msg' => '请完成企业或个人认证',
            'action' => 'need_verify_company',
        ],
        'NEED_ORG_MEMBERSHIP' => [
            'code' => 402,
            'msg' => '您未加入有效组织',
            'action' => 'contact_org_admin',
        ],
        'NEED_REGION_ASSIGNMENT' => [
            'code' => 402,
            'msg' => '未分配区域或角色无效',
            'action' => 'contact_admin',
        ],
        'LOGIN_FAILED' => [
            'code' => 402,
            'msg' => '登录验证失败',
            'action' => 'login_failed',
        ],
        'CLIENT_NOT_ALLOWED' => [
            'code' => 403,
            'msg' => '当前客户端不允许登录',
            'action' => 'client_not_allowed',
        ],
    ];

    public function verifyUser(array $login): array
    {
        switch ($login['status']) {
            case 'error':
                return $this->rule('LOGIN_FAILED', $login['msg']);
            case 'need_bind_phone':
                return $this->rule('NEED_BIND_PHONE');
            case 'success':
                /** @var User $user */
                $user = $login['user'];
                if ((int)$user->status !== 1) {
                    Log::warning('用户[{user}]已被禁用', ['user' => $user->id, 'status' => $user->status]);
                    return $this->rule('LOGIN_FAILED', '用户已被禁用');
                }

                $client = strtolower((string)Request::header('X-Client', 'seller'));

                if ($client !== 'buyer' && $this->hasAdminPrivilege($user)) {
                    return $this->rule('SUCCESS');
                }

                return match ($client) {
                    'admin', 'system' => $this->verifyAdminUser($user),
                    'seller' => $this->verifySellerUser($user),
                    'buyer' => $this->verifyBuyerUser($user),
                    default => $this->rule('CLIENT_NOT_ALLOWED', '未知客户端'),
                };
            default:
                return $this->rule('LOGIN_FAILED');
        }
    }

    private function verifyAdminUser(User $user): array
    {
        $allowedRoles = ['admin', 'support'];
        $roles = $user->roles()->whereIn('slug', $allowedRoles)->find();
        if (!$roles) {
            Log::warning('系统用户[{user}]缺少管理员角色', ['user' => $user->id]);
            return $this->rule('CLIENT_NOT_ALLOWED', '无权访问系统端');
        }
        return $this->rule('SUCCESS');
    }

    private function verifySellerUser(User $user): array
    {
        if ($this->hasAdminPrivilege($user)) {
            return $this->rule('SUCCESS');
        }

        $identity = $user->identities()
            ->whereIn('identity_type', ['seller', 'both'])
            ->where('status', 1)
            ->find();
        if (!$identity) {
            Log::warning('用户[{user}]无有效卖家身份', ['user' => $user->id]);
            return $this->rule('NEED_COMPANY_AUTH', '请完成企业认证');
        }

        $company = $user->company;
        if (!$company || (int)$company->status !== 1) {
            Log::warning('用户[{user}]企业认证未通过', ['user' => $user->id]);
            return $this->rule('NEED_COMPANY_AUTH', '企业认证未通过');
        }

        $orgMember = $user->orgMembers()
            ->with('org')
            ->where('status', 1)
            ->find();
        if (!$orgMember || !$orgMember->org || (int)$orgMember->org->status !== 1) {
            Log::warning('用户[{user}]未加入有效组织', ['user' => $user->id]);
            return $this->rule('NEED_ORG_MEMBERSHIP', '请联系管理员加入组织');
        }

        return $this->rule('SUCCESS');
    }

    private function verifyBuyerUser(User $user): array
    {
        $identity = $user->identities()
            ->whereIn('identity_type', ['buyer', 'seller', 'both'])
            ->where('status', 1)
            ->find();
        if ($identity) {
            return $this->rule('SUCCESS');
        }

        $individual = $user->individual;
        if ($individual && (int)$individual->status === 1) {
            return $this->rule('SUCCESS');
        }

        Log::warning('用户[{user}]缺少买家身份或认证', ['user' => $user->id]);
        return $this->rule('NEED_COMPANY_AUTH', '请完成个人或企业认证');
    }

    private function rule(string $name, string $msg = ''): array
    {
        $rule = self::RULES[$name] ?? self::RULES['LOGIN_FAILED'];
        if ($msg !== '') {
            $rule['msg'] = $msg;
        }
        return $rule;
    }

    private function hasAdminPrivilege(User $user): bool
    {
        $adminIdentities = ['admin', 'support'];
        $identityExists = $user->identities()
            ->whereIn('identity_type', $adminIdentities)
            ->where('status', 1)
            ->find();

        if ($identityExists) {
            return true;
        }

        $adminRoles = ['admin', 'support', 'system_admin'];
        return (bool) $user->roles()->whereIn('slug', $adminRoles)->find();
    }
}
